package com.hxkj.service.impl;

import com.hxkj.client.service.BrokerOrderPayServiceClient;
import com.hxkj.dao.CommonPaymentDao;
import com.hxkj.domain.bo.Form;
import com.hxkj.domain.bo.PayAPI;
import com.hxkj.domain.bo.PayParameter;
import com.hxkj.domain.enums.PaymentStatusEnum;
import com.hxkj.domain.po.*;
import com.hxkj.service.ShunchangPayService;
import com.hxkj.utils.FormUtil;
import com.hxkj.utils.MD5Util;
import com.hxkj.utils.PayUtil;
import com.hxkj.utils.UUIDUtil;
import com.platform.common.domain.exception.CustomMessageException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * 顺畅支付服务
 * <p>
 * Create by chenwei on 2018/8/17 15:32
 */
@Service("shunchangPayService")
@Slf4j
public class ShunchangPayServiceImpl implements ShunchangPayService {
    @Resource
    private CommonPaymentDao commonPaymentDao;

    @Resource
    private BrokerOrderPayServiceClient brokerOrderPayServiceClient;

    private final static String UID = "735";

    private final static String TOKEN = "6c0b9973780e95bd4543dfcf7fd324b5";

    // 异步通知url
    @Value("${pay.shunchang.rechargeNotifyUrl}")
    private String NOTIFY_URL;

    // 顺畅支付接口常量 1 为支付宝
    private final static String ALIPAY = "1";
    // 2 为微信支付
    private final static String WECHATPAY = "2";

    private final static String PAY_URL = "http://zhifu.baike.com/pay";

    // 业务方订单支付成功状态
    private final static String PAY_SUCCESS = "15";

    @Override
    public String pay(PayParameter payParameter) throws Exception {
        Long now = System.currentTimeMillis();
        // 判断订单是否被创建
        List<CommonPayment> commonPayments = commonPaymentDao.get(CommonPayment.builder().orderId(payParameter.getId()).build());
        // 没有创建订单
        if (commonPayments.isEmpty()) {
            // 生成本地支付订单
            String id = UUIDUtil.generateUUID();
            CommonPayment commonPayment = CommonPayment.builder().id(id).amount(payParameter.getAmount())
                    // 业务订单号
                    .orderId(payParameter.getId())
                    // 商品名称
                    .product(payParameter.getName())
                    // 创建时间
                    .createTime(now)
                    // 更新时间
                    .updateTime(now)
                    // 订单状态
                    .status(PaymentStatusEnum.NON_PAYMENY.getType())
                    // 渠道
                    .payChannel(payParameter.getPayType())
                    .build();
            commonPaymentDao.save(commonPayment);
            // 构建支付请求
            payParameter.setId(id);
            return generatePaymentOrder(payParameter);
            // 已经创建了支付订单
        } else {
            // 判断订单状态,若支付,则返回已支付,若未支付,则继续支付
            CommonPayment commonPayment = commonPayments.get(0);
            // 若该订单未支付 继续支付
            if (StringUtils.equals(commonPayment.getStatus(), PaymentStatusEnum.NON_PAYMENY.getType())) {
                payParameter.setId(commonPayment.getId());
                return generatePaymentOrder(payParameter);
            } else {
                // 关闭或者已支付则不继续支付
                throw new CustomMessageException(400, "当前订单已经被支付");

            }
        }
    }

    @Override
    public String nodify(PayAPI payAPI) throws Exception {
        // 验证秘钥
        if (PayUtil.checkPayKey(payAPI)) {
            List<CommonPayment> commonPayments = commonPaymentDao.get(CommonPayment.builder().id(payAPI.getOrderid()).build());
            // 验证订单是否存在
            if (!commonPayments.isEmpty()) {
                CommonPayment commonPayment = commonPayments.get(0);
                // 验证订单是否被处理
                if (!commonPayment.getStatus().equals(PaymentStatusEnum.NON_PAYMENY.getType())) {
                    // 通知顺畅支付
                    log.info("订单:{}已经被处理,将要通知顺畅支付", commonPayment.getOrderId());
                    return "OK";
                }
                // 否则修改订单状态为支付成功
                commonPayment.setUpdateTime(System.currentTimeMillis());
                commonPayment.setTradeStatus("TRADE_SUCCESS");
                commonPayment.setPayId(payAPI.getTrade_no());
                commonPayment.setBuyerPayAmount((new BigDecimal(payAPI.getRealprice())));
                commonPayment.setStatus(PaymentStatusEnum.PAIED.getType());
                commonPaymentDao.update(commonPayment);

                // ------ 通知业务调用方
                InsuranceOrder insuranceOrder = new InsuranceOrder();
                insuranceOrder.setOrderId(commonPayment.getOrderId());
                insuranceOrder.setOrderAmount(new BigDecimal(payAPI.getPrice()));
                // 支付成功
                insuranceOrder.setOrderStatus(PAY_SUCCESS);
                brokerOrderPayServiceClient.callback(insuranceOrder);
                // 通知业务方
                return "OK";
            } else {
                log.error("异步回调找不到订单:,订单号为:{}", payAPI.getOrderid());
                return "fail";
            }
        } else {
            log.error("异步回调签名验证失败:,订单号为:{}", payAPI.getOrderid());
            // 失败
            return "fail";
        }
    }


    /**
     * 生成顺畅支付表单
     *
     * @param payParameter
     * @throws Exception
     */
    private String generatePaymentOrder(PayParameter payParameter) throws Exception {
        // 构建支付表单
        Form form = Form.builder().action(PAY_URL)
                .goodsName(payParameter.getName())
                // 1 为支付宝
                .istype(ALIPAY)
                .method("POST")
                .notify_url(NOTIFY_URL)
                .orderid(payParameter.getId())
                .orderuid(payParameter.getId())
                .price(payParameter.getAmount().toString())
                .return_url("null")
                .uid(UID)
                .build();
        String originalKey = form.getGoodsName() + form.getIstype() + form.getNotify_url() + form.getOrderid()
                + form.getOrderuid()
                + form.getPrice()
                + form.getReturn_url()
                + TOKEN + form.getUid();
        String key = MD5Util.encodePassword(originalKey);
        log.info("加密后秘钥:{}", key);
        form.setKey(key);
        return FormUtil.createForm(form);
    }
}
